步骤 4:添加生成器表达式¶
Generator expressions
在构建系统生成期间被评估,以生成特定于每个构建配置的信息。
Generator expressions
允许在许多目标属性的上下文中使用,例如 LINK_LIBRARIES
、 INCLUDE_DIRECTORIES
、 COMPILE_DEFINITIONS
等等。 它们也可以在使用命令填充这些属性时使用,例如 target_link_libraries()
、 target_include_directories()
、 target_compile_definitions()
等等。
Generator expressions
可以用于启用条件链接、编译时使用的条件定义、条件包含目录等等。 条件可以基于构建配置、目标属性、平台信息或任何其他可查询的信息。
有不同类型的 generator expressions
,包括逻辑表达式、信息表达式和输出表达式。
逻辑表达式用于创建条件输出。 基本表达式是 0
和 1
表达式。 $<0:...>
产生空字符串,而 $<1:...>
产生 ...
的内容。 它们也可以嵌套。
练习 1 - 使用生成器表达式添加编译器警告标志¶
generator expressions
的常见用法是条件性地添加编译器标志,例如用于语言级别或警告的标志。 一个好的模式是将此信息与 INTERFACE
目标关联,从而允许此信息传播。
目标¶
在构建时添加编译器警告标志,但不为已安装版本添加。
有用的资源¶
要编辑的文件¶
CMakeLists.txt
开始¶
打开文件 Step4/CMakeLists.txt
并完成 TODO 1
到 TODO 4
。
首先,在顶层 CMakeLists.txt
文件中,我们需要将 cmake_minimum_required()
设置为 3.15
。 在本练习中,我们将使用 CMake 3.15 中引入的生成器表达式。
接下来,我们添加项目所需的编译器警告标志。 由于警告标志因编译器而异,我们使用 COMPILE_LANG_AND_ID
生成器表达式来控制给定语言和一组编译器 ID 时应用哪些标志。
构建和运行¶
创建一个名为 Step4_build
的新目录,运行 cmake
可执行文件或 cmake-gui
来配置项目,然后使用您选择的构建工具或通过在构建目录中使用 cmake --build .
来构建它。
mkdir Step4_build
cd Step4_build
cmake ../Step4
cmake --build .
解决方案¶
更新 cmake_minimum_required()
以要求至少 CMake 版本 3.15
TODO 1: 点击显示/隐藏答案
cmake_minimum_required(VERSION 3.15)
接下来,我们确定我们的系统当前正在使用哪个编译器进行构建,因为警告标志因我们使用的编译器而异。 这是通过 COMPILE_LANG_AND_ID
生成器表达式完成的。 我们将结果设置在变量 gcc_like_cxx
和 msvc_cxx
中,如下所示
TODO 2: 点击显示/隐藏答案
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
接下来,我们添加项目所需的编译器警告标志。 使用我们的变量 gcc_like_cxx
和 msvc_cxx
,我们可以使用另一个生成器表达式,仅在变量为真时才应用相应的标志。 我们使用 target_compile_options()
将这些标志应用于我们的接口库。
TODO 3: 点击显示/隐藏答案
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
"$<${msvc_cxx}:-W3>"
)
最后,我们只希望在构建期间使用这些警告标志。 我们已安装项目的消费者不应继承我们的警告标志。 为了指定这一点,我们使用 BUILD_INTERFACE
条件将来自 TODO 3 的标志包装在生成器表达式中。 生成的完整代码如下所示
TODO 4: 点击显示/隐藏答案
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)